/*****************************************************************************
*    Copyright (C)2007 Ali Corporation. All Rights Reserved.
*
*    File:    Tun_MxL136.c
*
*    Description:    Source file of MAXLINEAR MxL136 TUNER.
*    History:
*           Date          Author                 Version          Reason
*	    ============	=============	=========	=================
*   4.17.2008	     David.Deng	      Ver 0.1	     Create file.
*****************************************************************************/
#include <sys_config.h>
#include <retcode.h>
#include <types.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <bus/i2c/i2c.h>
#include <osal/osal.h>
#include "tun_mxl136.h"
#include <hld/nim/nim_dev.h>

#if ((SYS_TUN_MODULE == MXL136) || (SYS_TUN_MODULE == ANY_TUNER))

#define NIM_PRINTF(...)

#define MXL_DVBT_DEBUG  0
#if(MXL_DVBT_DEBUG) 
#define NIM_MXL136_PRINTF  soc_printf
#else
#define NIM_MXL136_PRINTF(...)
#endif

struct COFDM_TUNER_CONFIG_EXT stMxL136_Config[2];
static MxL136_TunerConfigS Mxl136_TunerConfig[2];
static BOOL bMxl_Tuner_Inited[2];
static UINT32 tuner_cnt = 0;

#ifdef MXL_DEBUG
UINT8 reg_dump[256];
#endif
/*****************************************************************************
* INT32 tun_mxl136_init(struct COFDM_TUNER_CONFIG_EXT * ptrTuner_Config)
*
* Tuner mxl136 Initialization
*
* Arguments:
*  Parameter1: struct COFDM_TUNER_CONFIG_EXT * ptrTuner_Config		: pointer for Tuner configuration structure 
*
* Return Value: INT32			: Result
*****************************************************************************/
INT32 tun_mxl136_init(UINT32 *tuner_id, struct COFDM_TUNER_CONFIG_EXT * ptrTuner_Config)
{
	MxL136_ChipVersion chip_ver=0;
	/* check Tuner Configuration structure is available or not */
	if ((ptrTuner_Config == NULL))
		return ERR_FAILUE;

	if(tuner_cnt >= MAX_TUNER_SUPPORT_NUM)
		return ERR_FAILUE;

	MEMCPY(&stMxL136_Config[tuner_cnt], ptrTuner_Config, sizeof(struct COFDM_TUNER_CONFIG_EXT));

	Mxl136_TunerConfig[tuner_cnt].tuner_id = tuner_cnt;
	Mxl136_TunerConfig[tuner_cnt].I2C_Addr = (MxL136_I2CAddr)(stMxL136_Config[tuner_cnt].cTuner_Base_Addr);
	Mxl136_TunerConfig[tuner_cnt].Mode = MxL_MODE_ISDBT;
	Mxl136_TunerConfig[tuner_cnt].IF_Freq = (MxL136_IF_Freq)(stMxL136_Config[tuner_cnt].wTuner_IF_Freq*1000);//(4000*1000)
	Mxl136_TunerConfig[tuner_cnt].CH_UNIT     = 1 ;
	Mxl136_TunerConfig[tuner_cnt].CH          = 14 ;
	//Mxl136_TunerConfig[tuner_cnt].RF_freq_kHz = RF_freq_kHz_DEFAULT ;
	Mxl136_TunerConfig[tuner_cnt].RF_Freq_Hz  = 473143*1000 ;
	Mxl136_TunerConfig[tuner_cnt].Xtal_Freq = (MxL136_Xtal_Freq)(stMxL136_Config[tuner_cnt].cTuner_Crystal*1000);
	Mxl136_TunerConfig[tuner_cnt].BW_MHz = MxL_BW_6MHz;
	Mxl136_TunerConfig[tuner_cnt].ClkOut_Setting = MxL_CLKOUT_ENABLE ;
	Mxl136_TunerConfig[tuner_cnt].ClkOut_Amp = MxL_CLKOUT_AMP_0 ;   //MxL_CLKOUT_AMP_7
	Mxl136_TunerConfig[tuner_cnt].IF_Diff_Out_Level = -8 ;
	Mxl136_TunerConfig[tuner_cnt].IF_Spectrum = MxL_NORMAL_IF ;

    if(tuner_cnt == 0)
    {
        Mxl136_TunerConfig[tuner_cnt].ClkOut_Setting = MxL_CLKOUT_ENABLE;
        Mxl136_TunerConfig[tuner_cnt].ClkOut_Amp = MxL_CLKOUT_AMP_0;
    }
    else
    {
		Mxl136_TunerConfig[tuner_cnt].ClkOut_Setting = MxL_CLKOUT_DISABLE;
    }

	bMxl_Tuner_Inited[tuner_cnt] = FALSE;
    
	if (tuner_id)
		*tuner_id = tuner_cnt;


	chip_ver=MxL_Check_ChipVersion(&Mxl136_TunerConfig[tuner_cnt]);
	NIM_MXL136_PRINTF("chip_ver=%x\n",chip_ver);

	tuner_cnt++;

	return SUCCESS;
}

/*****************************************************************************
* INT32 tun_mxl136_status(UINT8 *lock)
*
* Tuner read operation
*
* Arguments:
*  Parameter1: UINT8 *lock		: Phase lock status
*
* Return Value: INT32			: Result
*****************************************************************************/

INT32 tun_mxl136_status(UINT32 tuner_id, UINT8 *lock)
{
	BOOL IfLock;

	if(tuner_id >= MAX_TUNER_SUPPORT_NUM)
		return ERR_FAILUE;

	MxL_RFSynth_Lock_Status(&Mxl136_TunerConfig[tuner_id], &IfLock);

	*lock = ( IfLock == TRUE ) ? 1 : 0; 
	if(IfLock == TRUE)
	{
		NIM_MXL136_PRINTF("MXL136 RF LOCK!!!\n");
	}

	return SUCCESS;
}

MxL_ERR_MSG MxL_Loop_Through_On(MxL136_TunerConfigS* myTuner, MxL136_LoopThru isOn)
{	
	UINT8 pArray[2];	// a array pointer that store the addr and data pairs for I2C write	
	
	pArray[0]=0x04;
	if(isOn)
		pArray[1]= 0x01;
	else
		pArray[1]= 0x0;

	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2,myTuner->tuner_id))
		return MxL_ERR_OTHERS;

	return MxL_OK;
}

INT32 MxL_TUNER_INIT( MxL136_TunerConfigS *mytuner )
{
	MxL_ERR_MSG Status ;

	mytuner->Mode = MxL_MODE_ISDBT ;
	mytuner->Xtal_Freq = MxL_XTAL_24_MHZ ;
	mytuner->BW_MHz = MxL_BW_6MHz ;
	mytuner->ClkOut_Setting = MxL_CLKOUT_ENABLE ;
	mytuner->ClkOut_Amp = MxL_CLKOUT_AMP_0 ;
	mytuner->IF_Diff_Out_Level = -8 ;
	mytuner->IF_Spectrum = MxL_NORMAL_IF ;

	Status = MxL_Loop_Through_On( mytuner, MxL_LT_DISABLE );
	if (Status != MxL_OK)
	{
		return ERR_FAILUE;
	}

	Status = MxL_Tuner_Init( mytuner ) ;
	if (Status != MxL_OK)
	{
		return ERR_FAILUE;
	}

	Status = MxL_Tuner_RFTune( mytuner, mytuner->RF_Freq_Hz, mytuner->BW_MHz ) ;
	if (Status != MxL_OK)
	{
		return ERR_FAILUE;
	}

	Status = MxL_Set_Register(mytuner, 0x00, 61);
	if (Status != MxL_OK)
	{
		return ERR_FAILUE;
    	}

	return SUCCESS ;
}

/*****************************************************************************
* INT32 tun_mxl136_control(UINT32 freq, UINT8 bandwidth,UINT8 AGC_Time_Const,UINT8 *data,UINT8 _i2c_cmd)
*
* Tuner write operation
*
* Arguments:
*  Parameter1: UINT32 freq		: Synthesiser programmable divider
*  Parameter2: UINT8 bandwidth		: channel bandwidth
*  Parameter3: UINT8 AGC_Time_Const	: AGC time constant
*  Parameter4: UINT8 *data		: 
*
* Return Value: INT32			: Result
*****************************************************************************/
INT32 tun_mxl136_control(UINT32 tuner_id, UINT32 freq, UINT8 bandwidth,UINT8 AGC_Time_Const,UINT8 *data,UINT8 _i2c_cmd)	
{
	unsigned long dwRF_Freq_KHz;
	MxL136_BW_MHz mxl_BW;
	MxL_ERR_MSG Status;

	if(tuner_id >= MAX_TUNER_SUPPORT_NUM)
	{
		return ERR_FAILUE;
	}

	if ( bMxl_Tuner_Inited[tuner_id] == FALSE )
	{
//		Mxl136_TunerConfig[tuner_id].tuner_id = tuner_id;
//		Mxl136_TunerConfig[tuner_id].I2C_Addr = (MxL136_I2CAddr)(stMxL136_Config[tuner_id].cTuner_Base_Addr);
//		Mxl136_TunerConfig[tuner_id].Mode = MxL_MODE_ISDBT;
//		Mxl136_TunerConfig[tuner_id].IF_Diff_Out_Level = -8;
//		Mxl136_TunerConfig[tuner_id].Xtal_Freq = (MxL136_Xtal_Freq)(stMxL136_Config[tuner_id].cTuner_Crystal*1000);
//		Mxl136_TunerConfig[tuner_id].IF_Freq = (MxL136_IF_Freq)(stMxL136_Config[tuner_id].wTuner_IF_Freq*1000);
//		Mxl136_TunerConfig[tuner_id].IF_Spectrum = MxL_NORMAL_IF;
//		Mxl136_TunerConfig[tuner_id].ClkOut_Setting = MxL_CLKOUT_ENABLE;
//		Mxl136_TunerConfig[tuner_id].ClkOut_Amp = MxL_CLKOUT_AMP_0;
//    	Mxl136_TunerConfig[tuner_id].CH_UNIT     = 1 ;
//    	Mxl136_TunerConfig[tuner_id].CH          = 14 ;
//    	Mxl136_TunerConfig[tuner_id].BW_MHz = MxL_BW_6MHz;
//      Mxl136_TunerConfig[tuner_id].RF_Freq_Hz  = freq*1000 ;

    	MxL_Loop_Through_On( &Mxl136_TunerConfig[tuner_id] , MxL_LT_DISABLE );

    	Status = MxL_Tuner_Init(&Mxl136_TunerConfig[tuner_id]);
    	if(Status!= MxL_OK )
    	{
    	    NIM_MXL136_PRINTF("mxl136 init faile\n");
    		return ERR_FAILUE;
    		
    	}
		bMxl_Tuner_Inited[tuner_id] = TRUE;
	}

	dwRF_Freq_KHz = freq;
	mxl_BW = (MxL136_BW_MHz)bandwidth;
	Status = MxL_Tuner_RFTune( &Mxl136_TunerConfig[tuner_id] , dwRF_Freq_KHz*1000, mxl_BW);
	if(  Status != MxL_OK )
	{
	    NIM_MXL136_PRINTF("mxl136 rftune  faile\n");
		return ERR_FAILUE;
	}
	Status = MxL_Set_Register( &Mxl136_TunerConfig[tuner_id] , 0x00, 61);
	if (Status != MxL_OK)
	{
	    NIM_MXL136_PRINTF("mxl136 set reg faile\n");
		return ERR_FAILUE;
	}
	return SUCCESS;	
}


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//																		   //
//							Tuner Functions								   //
//																		   //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
MxL_ERR_MSG MxL_Set_Register(MxL136_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData)
{
	UINT32 Status=0;
	UINT8 pArray[2];
	pArray[0] = RegAddr;
	pArray[1] = RegData;
	Status = MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2, myTuner->tuner_id);
	if(Status)
	{
		return MxL_ERR_SET_REG;
	}

	return MxL_OK;
}

MxL_ERR_MSG MxL_Get_Register(MxL136_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData)
{
	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, RegAddr, RegData, myTuner->tuner_id))
		return MxL_ERR_GET_REG;
	return MxL_OK;

}

void ASSERT_REG0()
{
	UINT8 data;
	MxL_Get_Register(&Mxl136_TunerConfig[0], 0, &data);

	if(data != 0x3f)
	{
		ASSERT(0);
	}
}

MxL_ERR_MSG MxL_Soft_Reset(MxL136_TunerConfigS* myTuner)
{
	MxL_ERR_MSG Status = MxL_OK;	
	UINT8 reg_reset;
	reg_reset = 0xFF;
	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, &reg_reset, 1, myTuner->tuner_id))
	{
		Status = MxL_ERR_OTHERS;
	}
	return Status;
}

MxL_ERR_MSG MxL_Stand_By(MxL136_TunerConfigS* myTuner)
{
	UINT8 pArray[4];	// a array pointer that store the addr and data pairs for I2C write	
	
	pArray[0] = 0x01;
	pArray[1] = 0x0;
	pArray[2] = 0x0F;
	pArray[3] = 0x0;

	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 4 ,myTuner->tuner_id))
		return MxL_ERR_OTHERS;

	return MxL_OK;
}

MxL_ERR_MSG MxL_Wake_Up(MxL136_TunerConfigS* myTuner)
{
	UINT8 pArray[2];	// a array pointer that store the addr and data pairs for I2C write	
	
	pArray[0] = 0x01;
	pArray[1] = 0x01;

	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2,myTuner->tuner_id))
		return MxL_ERR_OTHERS;

	if(MxL_Tuner_RFTune(myTuner, myTuner->RF_Freq_Hz, myTuner->BW_MHz))
		return MxL_ERR_RFTUNE;

	return MxL_OK;
}

MxL_ERR_MSG MxL_Tuner_Init(MxL136_TunerConfigS* myTuner)
{	
	UINT8 pArray[MAX_ARRAY_SIZE];	// a array pointer that store the addr and data pairs for I2C write
	UINT32 Array_Size;							// a integer pointer that store the number of element in above array
	MxL_ERR_MSG status;

	//Soft reset tuner
	status = MxL_Soft_Reset(myTuner);
	if( status )
	{
		return MxL_ERR_INIT;
	}

	MxL_Delay(10);
	//perform initialization calculation
	MxL136_Init(pArray, &Array_Size, (UINT8)myTuner->Mode, myTuner->IF_Diff_Out_Level, (UINT32)myTuner->Xtal_Freq, 
				(UINT32)myTuner->IF_Freq, (UINT8)myTuner->IF_Spectrum, (UINT8)myTuner->ClkOut_Setting, (UINT8)myTuner->ClkOut_Amp);

	//perform I2C write here
	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size,myTuner->tuner_id))
		return MxL_ERR_INIT;

	return MxL_OK;
}


MxL_ERR_MSG MxL_Tuner_RFTune(MxL136_TunerConfigS* myTuner, UINT32 RF_Freq_Hz, MxL136_BW_MHz BWMHz)
{
	UINT32 Status=0;
	UINT8 pArray[MAX_ARRAY_SIZE];	// a array pointer that store the addr and data pairs for I2C write
	UINT32 Array_Size;							// a integer pointer that store the number of element in above array

	//Store information into struc
	myTuner->RF_Freq_Hz = RF_Freq_Hz;
	myTuner->BW_MHz = BWMHz;

	//perform Channel Change calculation
	MxL136_RFTune(pArray,&Array_Size,RF_Freq_Hz,BWMHz);

	//perform I2C write here
	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size,myTuner->tuner_id))
		return MxL_ERR_RFTUNE;

	//wait for 3ms
	MxL_Delay(3); 

	return MxL_OK;
}

MxL136_ChipVersion MxL_Check_ChipVersion(MxL136_TunerConfigS* myTuner)
{	
	UINT8 Data;
	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD9, &Data, myTuner->tuner_id))
		return MxL_GET_ID_FAIL;

	switch(Data)
	{
		case 0x14:
			return MxL_136RF_ID;
			break;

		default:
			return MxL_UNKNOWN_ID;
	}
}

MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL136_TunerConfigS* myTuner, BOOL* isLock)
{	
	UINT8 Data;
	*isLock = FALSE; 
	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data,myTuner->tuner_id))
		return MxL_ERR_OTHERS;
	Data &= 0x0C;
	if (Data == 0x0C)
		*isLock = TRUE;  //RF Synthesizer is Lock	
	return MxL_OK;
}

MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL136_TunerConfigS* myTuner, BOOL* isLock)
{
	UINT8 Data;
	*isLock = FALSE; 
	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data,myTuner->tuner_id))
		return MxL_ERR_OTHERS;
	Data &= 0x03;

	if (Data == 0x03)
	{
		*isLock = TRUE;   //REF Synthesizer is Lock
	}
	return MxL_OK;
}


/******************************************************************************
**
**  Name: MxL_I2C_Write
**
**  Description:    I2C write operations
**
**  Parameters:    	
**					DeviceAddr	- MxL136 Device address
**					pArray		- Write data array pointer
**					count		- total number of array
**
**  Returns:        0 if success
**
**  Revision History:
**
**   SCR      Date      Author  Description
**  -------------------------------------------------------------------------
**   N/A   12-16-2007   khuang initial release.
**
******************************************************************************/
//#if defined(BURST_PAIR_SZ)
//#error " BURST_PAIR_SZ already defined!"
//#else
//#define BURST_PAIR_SZ   6
#define BURST_SZ 6
//#endif

//extern UINT32 MB86A2x_write( UINT8 OFDM_adr, UINT8 address , UINT8 value );
#if(SYS_DEM_MODULE == TC90527)
extern BOOL I2cWrite2TC90527(UINT8 reg_add, UINT8* data,UINT8 len);
extern UINT8	I2cAddr;
#endif

#if 0

typedef enum {
	I2C_OK = 1,
	I2C_NG = 0
} I2C_ACCCESS ;
/****************************************************************************
/*	MB86A21 I2C Write Access
/*	Return value  OK:1, NG;0
****************************************************************************/
static UINT32 MB86A2x_write( UINT8 OFDM_adr, UINT8 address , UINT8 value, UINT32 tuner_id) 
{
	/*
	SINT32 i2cok ;
	
	i2cok =  I2Cwrite( OFDM_adr, address, value ) ;

	if( i2cok==1 ) return I2C_OK ;
	else           return I2C_NG ;
	*/
	UINT8 i2cBuf[4];

	i2cBuf[0] = address;
	i2cBuf[1] = value;
	if( i2c_write( stMxL136_Config[tuner_id].i2c_type_id, OFDM_adr , i2cBuf , 2 ) )
	{
		return I2C_NG;
	}
	return I2C_OK ;
}

/****************************************************************************
/*	MB86A21 I2C Read Access
/*	Return value  OK:1, NG;0
****************************************************************************/
static UINT32 MB86A2x_read( UINT8 OFDM_adr, UINT8 address , UINT8 *value, UINT32 tuner_id) 
{
	/*
	SINT32 i2cok ;

	i2cok =  I2Cread( OFDM_adr, address, value ) ;

	if( i2cok==1 ) return I2C_OK ;
	else           return I2C_NG ;
	*/
	UINT8 i2cBuf[2];

	i2cBuf[0] = address;
	i2c_write( stMxL136_Config[tuner_id].i2c_type_id, OFDM_adr , i2cBuf , 1 );

	MEMSET( i2cBuf , 0 , sizeof(i2cBuf) );
	i2c_read( stMxL136_Config[tuner_id].i2c_type_id, OFDM_adr , i2cBuf , 1 );
	*value = i2cBuf[0];

	return I2C_OK ;
}
#endif


UINT32 MxL_I2C_Write(UINT8 DeviceAddr, UINT8* pArray, UINT32 count, UINT32 tuner_id)
{
/*
#if(SYS_DEM_MODULE == TC90527)
    UINT32 ret;
    UINT8 pI2cBuf[MAX_ARRAY_SIZE+4];
    pI2cBuf[0] = 0xFE;
    pI2cBuf[1] = DeviceAddr;
    MEMCPY( pI2cBuf + 2 , pArray , count );
    ret = i2c_gpio_write(0, I2cAddr , pI2cBuf, count + 2);
    return ret;
#else
	if ( !count )
	{
		return 0;
	}

	MB86A2x_write( MB86A2x_Adr_DEFAULT , 0xFE , 00, tuner_id );
	return i2c_write( stMxL136_Config[tuner_id].i2c_type_id, DeviceAddr , pArray , count );
#endif
*/
	int status = 0;
	int i,j;
	UINT8 szBuffer[BURST_SZ];
	UINT16 BurstNum, RemainLen;


	if ( !count ) return 0;


	RemainLen = count % BURST_SZ; 
	if ( RemainLen )
	{
		BurstNum = count / BURST_SZ; 
	}
	else
	{
		BurstNum = count / BURST_SZ - 1;
		RemainLen = BURST_SZ;
	}

	for ( i = 0 ; i < BurstNum; i ++ )
	{
		for ( j = 0 ; j < BURST_SZ ; j++  )
		{
			szBuffer[j]   = pArray[i * BURST_SZ + j ];             // addr
			//szBuffer[j+1] = pArray[i * BURST_PAIR_SZ + j +1];	// value

		}
		
		status = stMxL136_Config[tuner_id].Tuner_Write(stMxL136_Config[tuner_id].i2c_type_id, stMxL136_Config[tuner_id].cTuner_Base_Addr, szBuffer, BURST_SZ);
		if(status!=0)
		{	
			NIM_MXL136_PRINTF("MXL136 WR1 err=%d\n",status);
			;
		}
	}

	

	for ( i = 0 ; i < RemainLen ; i++ )
	{
		szBuffer[i]   = pArray[BurstNum * BURST_SZ + i ];         // addr 
		//szBuffer[i+1] = pArray[BurstPairs * BURST_PAIR_SZ + i+1 ];   // value
		// libc_printf("%x  %x \n", szBuffer[i] , szBuffer[i+1]  );
	}

	status += stMxL136_Config[tuner_id].Tuner_Write(stMxL136_Config[tuner_id].i2c_type_id, stMxL136_Config[tuner_id].cTuner_Base_Addr, szBuffer, RemainLen);
	if(status!=0)
	{		
			NIM_MXL136_PRINTF("MXL136 WR2 err=%d\n",status);
			;
	}
	
	return status;
}

/******************************************************************************
**
**  Name: MxL_I2C_Read
**
**  Description:    I2C read operations
**
**  Parameters:    	
**					DeviceAddr	- MxL136 Device address
**					Addr		- register address for read
**					*Data		- data return
**
**  Returns:        0 if success
**
**  Revision History:
**
**   SCR      Date      Author  Description
**  -------------------------------------------------------------------------
**   N/A   12-16-2007   khuang initial release.
**
******************************************************************************/
UINT32 MxL_I2C_Read(UINT8 DeviceAddr, UINT8 Addr, UINT8* mData, UINT32 tuner_id)
{
/*
#if(SYS_DEM_MODULE == TC90527)
    UINT32 ret;
    UINT8 pI2cBuf[MAX_ARRAY_SIZE+4];
    pI2cBuf[0] = 0xFE;
    pI2cBuf[1] = DeviceAddr;
    pI2cBuf[2] = 0xFB;
    pI2cBuf[3] = Addr;
    i2c_gpio_write( 0 , I2cAddr , pI2cBuf , 4 );

    pI2cBuf[1] = (DeviceAddr|0x01);
    i2c_gpio_write_no_stop( 0 , I2cAddr , pI2cBuf , 2 );
    ret = i2c_gpio_read( 0 , I2cAddr , mData , 1 );
    return ret;
#else
	UINT8 Read_Cmd[2]; 

	MB86A2x_write( MB86A2x_Adr_DEFAULT , 0xFE , 00, tuner_id);

	Read_Cmd[0] = 0xFB;
	Read_Cmd[1] = Addr;
	if( i2c_write( stMxL136_Config[tuner_id].i2c_type_id , DeviceAddr , Read_Cmd , 2 ) != 0 )
	{
		return ERR_FAILURE;
	}

	MB86A2x_write( MB86A2x_Adr_DEFAULT , 0xFE , 00, tuner_id);
	if( i2c_read( stMxL136_Config[tuner_id].i2c_type_id , DeviceAddr , mData , 1 ) != 0 )
	{
		return ERR_FAILURE;
	}

	return SUCCESS;
#endif
*/
UINT8 Read_Cmd[2]; 
int status = 0;
	/* read step 1. accroding to mxl5007 driver API user guide. */
	Read_Cmd[0] = 0xFB;
	Read_Cmd[1] = Addr;
	status=stMxL136_Config[tuner_id].Tuner_Write(stMxL136_Config[tuner_id].i2c_type_id, stMxL136_Config[tuner_id].cTuner_Base_Addr, Read_Cmd, 2);
	if(status!=0)
	{		
			NIM_MXL136_PRINTF("MXL136 RD1 err=%d\n",status);
			;
	}
	status += stMxL136_Config[tuner_id].Tuner_Read(stMxL136_Config[tuner_id].i2c_type_id, stMxL136_Config[tuner_id].cTuner_Base_Addr, mData, 1);
	if(status!=0)
	{		
			NIM_MXL136_PRINTF("MXL136 RD2 err=%d\n",status);
			;
	}
	return status;
}

/******************************************************************************
**
**  Name: MxL_Delay
**
**  Description:    Delay function in milli-second
**
**  Parameters:    	
**					mSec		- milli-second to delay
**
**  Returns:        0
**
**  Revision History:
**
**   SCR      Date      Author  Description
**  -------------------------------------------------------------------------
**   N/A   12-16-2007   khuang initial release.
**
******************************************************************************/
void MxL_Delay(UINT32 mSec)
{
	osal_task_sleep(mSec);
}

INT32 tun_mxl136_powcontrol(UINT32 tuner_id, UINT8 stdby)
{
    MxL_ERR_MSG Status;

	if(tuner_id >= MAX_TUNER_SUPPORT_NUM)
		return ERR_FAILUE;

	if (stdby)
	{
		if ((Status = MxL_Stand_By(&Mxl136_TunerConfig[tuner_id]))!=MxL_OK)
		{
			return ERR_FAILUE;
		}
	}
	else
	{
		if ((Status = MxL_Wake_Up(&Mxl136_TunerConfig[tuner_id]))!=MxL_OK)
		{
			return ERR_FAILUE;
		}
	}

	return SUCCESS;
}

INT32 tun_mxl136_command(UINT32 tuner_id, INT32 cmd, UINT32 param)
{
    INT32 ret = SUCCESS;

    switch(cmd)
    {
        case NIM_TUNER_POWER_CONTROL:
            tun_mxl136_powcontrol(tuner_id, param);
            break;

        default:
            ret = ERR_FAILUE;
            break;
    }

    return ret;
}


#endif
